package com.beiding.my.mql;

import com.beiding.my.mql.utils.*;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class MQLBuilder {

    /*
       mql是一种伪sql语法
       支持多表关联查询和返回

       例如:
           select a.name,a.b1.name,a.b2.name from Student a where a.b1.name= :p1

       自动编译 => SELECT a.name AS f1,b1.name AS f2,b2.name AS f3 FROM student_be a,teacher_be b1,teacher_be b2,_quote_teacher_be q1,_quote_teacher_be q2 WHERE a.id = q1.`_student_be_a` AND b1.`id`=q1.`self` AND a.`id`=q2.`_student_be_b` AND b2.`id`=q2.`self` and b1.name = :p1

       //必须有类型声明

        a.b

        B被A引用,将可以得到引用B的详情:
            中间表的表名,B被A引用在中间表中的列名,以及指向B的self字段在中间表中的列名,以及A的id字段在A表中的列名,B的id字段在表中的列名

     */

    private Map<String, MQLCompiler> mqlCompilerMap = new HashMap<>();

    public MQLBuilder(List<MQLCompiler> mqlCompilers) {
        for (MQLCompiler compiler : mqlCompilers) {
            mqlCompilerMap.put(compiler.getCommand(), compiler);
        }
    }


    public MQLExecutor build(String mql) {
        mql = mql.trim();

        mql = deepHandle(mql);

        return null;

    }


    //递归处理
    //深度处理
    public String deepHandle(String mql) {

        //最外层

        //屏蔽掉子句
        SubMqlHide subMqlHide = MqlUtils.hideSubMql(mql);

        //被屏蔽的所有子句
        List<Block> hindBlocks = subMqlHide.getHindBlocks();

        Map<Pair, String> rep = new HashMap<>();
        Map<String, String> placeHolderMap = new HashMap<>();
        for (Block hindBlock : hindBlocks) {
            String holder = createHolder();
            rep.put(hindBlock, holder);
            placeHolderMap.put(holder, deepHandle(hindBlock.getText()));
        }

        //屏蔽之后的结果
        String result = subMqlHide.getResult();

        //将带有占位符的结果注入回去
        result = MqlUtils.recover(result, rep);

        //进行裁切处理

        //进行裁切处理
        List<KeywordBlock> keywordBlocks = MqlUtils.splitMql(result);

        StringBuilder builder = new StringBuilder();

        for (KeywordBlock block : keywordBlocks) {

            //找到关键字
            String command = block.getKeyword();
            MQLCompiler mqlCompiler = mqlCompilerMap.get(command);
            if (mqlCompiler == null) {
                throw new NoSuchCommandException(command, mql);
            }
            builder.append(mqlCompiler.compile(block.getText()));
        }

        String k = builder.toString();

        //替换会占位符
        for (Map.Entry<String, String> stringStringEntry : placeHolderMap.entrySet()) {
            k = k.replace(stringStringEntry.getKey(), stringStringEntry.getValue());
        }

        return k;


    }

    private static int h = 1;

    private static String createHolder() {
        return "____________________" + h++ + "____________________";
    }


}
